package utils

import (
	"bytes"
	"fmt"
	"hash/crc32"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

//GetCurDir 获取当前文件执行的路径
func GetCurDir() string {
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}
	return strings.Replace(dir, "\\", "/", -1)
}

// 产生一个[left, right]左闭右闭区间的随机数，可以为负数，right必须大于等于left
func RandIntRange(left int, right int) int {
	//随机数生成器，加入时间戳保证每次生成的随机数不一样
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	return r.Intn(right-left+1) + left
}

// 产生一个[left, right]左闭右闭区间的随机数，可以为负数，right必须大于等于left
func RandInt64Range(left int64, right int64) int64 {
	//随机数生成器，加入时间戳保证每次生成的随机数不一样
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	return r.Int63n(right-left+1) + left
}

// 哈希算号器，对输入字符串的前4个字符进行算号，要求输入字符串长度至少4个字符（内部不会对长度进行校验）
func HashCode(str string) int {
	if len(str) < 4 {
		return 0
	}
	buf := []byte(str)[:4]
	return int(buf[3])<<24 | int(buf[2])<<16 | int(buf[1])<<8 | int(buf[0])
}

// String hashes a string to a unique hashcode.
// crc32 returns a uint32, but for our use we need
// and non negative integer. Here we cast to an integer
// and invert it if the result is negative.
func StringHash(s string) int {
	v := int(crc32.ChecksumIEEE([]byte(s)))
	if v >= 0 {
		return v
	}
	if -v >= 0 {
		return -v
	}
	return 0
}

// Strings hashes a list of strings to a unique hashcode.
func StringsHash(strings []string) string {
	var buf bytes.Buffer

	for _, s := range strings {
		buf.WriteString(fmt.Sprintf("%s-", s))
	}

	return fmt.Sprintf("%d", StringHash(buf.String()))
}
